#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
 #include <sys/stat.h>

// 错误设计目标：不当的“正确 API 使用方式”导致父进程退出、子进程继续运行并成为孤儿；
// 同时保留连带错误：
// - 错误1：在信号处理器中使用 printf（异步不安全）并直接 _exit(0)
// - 错误2：父进程不终止也不回收子进程（不 kill、不 wait）
// - 错误3：子进程 open() 日志但不 close()，造成 FD 泄漏
// - 错误4：umask(000)+0666 导致日志权限过宽
// - 错误5：忽略错误处理（不检查 setpgid/open/dprintf 失败）
// 注意：本错误版不再使用旧式 API（signal），统一采用 sigaction，但仍然是“不当用法”。

static void bad_handler(int sig) {
    // 异常：在异步信号上下文中调用 printf 属于异步不安全操作
    printf("got signal %d, exiting now\n", sig);
    _exit(0); // 直接退出父进程，导致子进程成为孤儿
}

static void install_parent_handlers(void) {
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = bad_handler;
    sigemptyset(&sa.sa_mask);
    // 依然不当：设置 SA_RESTART 掩盖部分系统调用中断，但处理器本身做了不安全操作并直接退出
    sa.sa_flags = SA_RESTART;
    (void)sigaction(SIGINT,  &sa, NULL);
    (void)sigaction(SIGTERM, &sa, NULL);
}

static void ignore_child_signals(void) {
    struct sigaction ia;
    memset(&ia, 0, sizeof(ia));
    ia.sa_handler = SIG_IGN;
    sigemptyset(&ia.sa_mask);
    ia.sa_flags = 0;
    (void)sigaction(SIGINT,  &ia, NULL);
    (void)sigaction(SIGTERM, &ia, NULL);
}

int main(int argc, char **argv) {
    (void)argc; (void)argv;

    // 父进程安装“不当”的处理器（使用 sigaction，但处理器内部做错事）
    install_parent_handlers();

    pid_t worker = fork();
    if (worker < 0) return 1;

    if (worker == 0) {
        // 子进程：忽略 SIGINT/SIGTERM，并自立为新进程组，确保前台 Ctrl-C 只命中父进程
        ignore_child_signals();
        setpgid(0, 0); // 不检查返回值（错误5）

        // 过宽权限 + FD 泄漏
        umask(000);
        const char *log_path = "./logs/collector.log";

        for (;;) {
            int fd = open(log_path, O_WRONLY | O_CREAT | O_APPEND, 0666);
            if (fd >= 0) {
                time_t now = time(NULL);
                char ts[32];
                strftime(ts, sizeof(ts), "%F %T", localtime(&now));
                dprintf(fd, "[%s] collector tick pid=%d\n", ts, getpid());
                // 故意不关闭，产生 FD 泄漏
                // close(fd);
            }
            sleep(1);
        }
        _exit(0);
    }

    // 父进程：不做任何子进程管理（不发送终止信号、不回收），仅阻塞等待信号
    for (;;) pause();
}
